package kz.pompei.var.core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import kz.pompei.var.atom.Atomizer;
import kz.pompei.var.instruction.BlockInstruction;
import kz.pompei.var.instruction.Instructionizer;
import kz.pompei.var.model.Context;

public class Compiler {
  private final ListErrorReciever errorReciever;
  private final Context context;
  
  private Instructionizer instructionizer;
  private Atomizer atomizer;
  
  private final List<String> scanDirList = new ArrayList<String>();
  
  public Compiler() {
    errorReciever = new ListErrorReciever();
    context = new Context(errorReciever);
  }
  
  public List<String> getScanDirList() {
    return scanDirList;
  }
  
  public void execute() throws Exception {
    for (String dir : scanDirList) {
      scanDir(dir, "");
    }
  }
  
  private static final String FS = File.separator;
  
  private void scanDir(String absoluteDirName, String relativeDirName) throws Exception {
    for (String name : new File(absoluteDirName).list()) {
      File file = new File(absoluteDirName + FS + name);
      if (file.isDirectory()) {
        scanDir(absoluteDirName + FS + name, relativeDirName + FS + name);
        continue;
      }
      if (file.isFile() && name.endsWith(".var")) {
        scanFile(file, relativeDirName);
      }
    }
  }
  
  public void setInstructionizer(Instructionizer instructionizer) {
    this.instructionizer = instructionizer;
  }
  
  public void setAtomizer(Atomizer atomizer) {
    this.atomizer = atomizer;
  }
  
  private BlockInstruction extractInstruction(File file) throws Exception {
    Atomizer atomizer = this.atomizer;
    Instructionizer instructionizer = this.instructionizer;
    
    atomizer.setReciever(instructionizer);
    atomizer.setErrorReciever(context.getErrorReciever());
    instructionizer.setErrorReciever(context.getErrorReciever());
    
    atomizer.start();
    instructionizer.start();
    
    BufferedReader br = new BufferedReader(
        new InputStreamReader(new FileInputStream(file), "UTF-8"));
    String line = null;
    while ((line = br.readLine()) != null) {
      atomizer.appendLine(line);
    }
    br.close();
    
    atomizer.finish();
    
    return instructionizer.finishAndGetInstruction();
  }
  
  private void scanFile(File file, String relativeDirName) throws Exception {
    BlockInstruction instruction = extractInstruction(file);
    
    System.out.println("Scan file " + file + " in " + relativeDirName + " - " + instruction);
  }
  
}
